const ffmpeg = require('fluent-ffmpeg');
const { PassThrough } = require('stream');
const fs = require('fs').promises;
const { Readable } = require('stream');


//设置exe路径
ffmpeg.setFfprobePath('C:/Users/xyxy0/AppData/Local/Microsoft/WinGet/Packages/Gyan.FFmpeg_Microsoft.Winget.Source_8wekyb3d8bbwe/ffmpeg-7.0.2-full_build/bin/ffprobe.exe')
ffmpeg.setFfmpegPath('C:/Users/xyxy0/AppData/Local/Microsoft/WinGet/Packages/Gyan.FFmpeg_Microsoft.Winget.Source_8wekyb3d8bbwe/ffmpeg-7.0.2-full_build/bin/ffmpeg.exe')


// 创建一个PassThrough流来存储转码后的数据
const outputStream = new PassThrough();


getMetadata("C:/Users/xyxy0/Videos/input.ts").then(v=>{
    console.dir(v)
})
return

ffmpeg(`concat:E:/js/video-split/out2.ts|out3.ts`)
// .inputOptions(`-i "concat:out2.ts|out3.ts"`)
.videoCodec('copy').output("ok.ts")
.outputOptions('-y')
.on('start', function (commandLine) {
    console.log('Spawned Ffmpeg with command: ' + commandLine);
}).run()

// ffmpeg('out2.ts')
//     .videoCodec('copy')
//     .input('out3.ts')
//     .on('start', function (commandLine) {
//         console.log('Spawned Ffmpeg with command: ' + commandLine);
//     })
//     .on('end', function () {
//         console.log('Merging finished !');
//     })
//     .mergeToFile('out4.ts', 'tempDir');

const outName = 'out3.ts'
ffmpeg("C:/Users/xyxy0/Videos/input.ts")
    .seekOutput('00:00:20')
    // .seekInput('00:00:15')
    // .seekInput(18*60)
    // .seekInput(-60)
    .duration(5.123456)
    .videoCodec('copy')
    .outputOptions('-y')
    .output(outName)
    .on('start', function (commandLine) {
        console.log('Spawned Ffmpeg with command: ' + commandLine);
    })
    .on('codecData', function (data) {
        console.log('------Input is ' + data.audio + ' audio ' +
            'with ' + data.video + ' video', data);
    })
    .on('error', function (err) {
        console.log('@@@@@@An error occurred: ' + err.message);
    })
    .on('end', async function (stdout, stderr) {
        // console.log('Transcoding succeeded !', stdout, stderr);
        const stats = await fs.stat(outName)
        console.log(stats)
        const prop = await getMetadata(outName)
        console.log(prop)
    })
// .saveToFile("test2.ts")
// .run()
function test() {
    const command = ffmpeg("C:/Users/xyxy0/Videos/input.ts")
        .noAudio()
        .seekInput('00:00:15')
        .outputFormat('mp4')
        .seekOutput('00:00:30')
        // .outputOptions('-y')
        // .outputOption('-movflags frag_keyframe+empty_moov')
        .outputOption('-movflags faststart+empty_moov')
        .videoCodec('copy')
        .on('codecData', function (data) {
            console.log('Input is ' + data.audio + ' audio ' +
                'with ' + data.video + ' video', data);
        })
        .on('error', function (err) {
            console.log('@@@@@@An error occurred: ' + err.message);
        })
        ;

    // .on('end', function () {
    //     console.log('Processing finished !');
    // })
    // .on('data', function(chunk) {
    //       console.log('ffmpeg just wrote ' + chunk.length + ' bytes');
    // })
    // .output("./out.ts")
    // .output(outStream)
    // .run()
    // .pipe(outStream, { end: true });

    // outputStream.pipe(fs.createWriteStream('output.ts'));
    const ffstream = command.pipe();
    let testLen = 0
    //100M
    // const b = Buffer.alloc(100 * 1024 * 1024, 0, 'binary');
    // let w = fs.createWriteStream(b, {
    //     flags: 'w',
    //     encoding: 'binary',
    //     fd: null,
    //     mode: 0o666,
    //     autoClose: true
    //   })
    const arr = new Uint8Array(100 * 1024 * 1024)
    ffstream.on('data', function (chunk) {
        // console.log('ffmpeg just wrote ' + chunk.length + ' bytes '+ (chunk instanceof Uint8Array) );
        // b.fill(chunk, testLen)
        arr.set(chunk, testLen)
        testLen += chunk.length
        // b= Buffer.concat([b, Buffer.from(chunk)])

    });
    ffstream.on('progress', function (progress) {
        console.log('Processing: ' + progress.percent + '% done, progress:', progress);
    })
    ffstream.on('end', async function (dd) {
        return
        const stats = await fs.stat("C:/Users/xyxy0/Videos/input.ts");
        const bufSize = stats.size + 1024 * 1024
        // const slicedBuffer =b.subarray(0,testLen);
        // console.log('Processing finished !', testLen, slicedBuffer.length, b.subarray(0,5));
        console.log('Processing finished !', testLen, arr.slice(0, 5), bufSize, dd)

        const stream = uint8ArrayToStream(arr.slice(0, testLen))
        ffmpeg(stream).on('start', function (commandLine) {
            console.log('Spawned Ffmpeg with command: ' + commandLine);
        }).on('codecData', function (data) {
            console.log('Input is ' + data.audio + ' audio ' +
                'with ' + data.video + ' video', data);
        }).on('progress', function (progress) {
            console.log('Processing: ' + progress.percent + '% done, progress:', progress);
        }).ffprobe(function (err, data) {
            console.log('file2 metadata:');
            console.dir(data);
        });
        // stream.pipe(fs.createWriteStream('output2.ts'))
        // getMetadata(stream).then((data)=>{
        //     console.dir(1111,data)
        // }, (err)=>console.error(err))
    })

}


//video_path -> Promise<metadata>
function getMetadata(filePath) {
    return new Promise((resolve, reject) => {
        ffmpeg.ffprobe(filePath, function (err, metadata) {
            if (err) return reject(err)
            resolve(metadata)
        });
    })
}


//Uint8Array -> Readable
function uint8ArrayToStream(uint8Array) {
    // 初始化位置
    let pos = 0
    return new Readable({
        read(size) {
            // 当流想要读取数据时，我们使用read方法
            if (pos < uint8Array.length) {
                // 通过push方法向流中传递数据
                const chunk = uint8Array.slice(pos, pos + size);
                this.push(chunk);
                pos += chunk.length;
            } else {
                // 当没有更多数据时，调用push null来结束流
                this.push(null);
            }
        }
    });
}
